#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
文件发送客户端 - 支持在macOS中运行，发送到Android Termux或本地测试
将本机文件（通常是mp4）发送到服务端
"""

import socket
import os
import sys
from datetime import datetime

class FileSendClient:
    def __init__(self, server_host, server_port=8888):
        self.server_host = server_host
        self.server_port = server_port
    
    def send_files(self, file_paths):
        """
        发送多个文件到服务端（顺序发送，每个文件独立连接）
        """
        if isinstance(file_paths, str):
            file_paths = [file_paths]
        
        total_files = len(file_paths)
        successful_files = []
        failed_files = []
        
        print(f"准备发送 {total_files} 个文件")
        print("=" * 50)
        
        for i, file_path in enumerate(file_paths, 1):
            print(f"\n[{i}/{total_files}] 正在处理: {os.path.basename(file_path)}")
            
            if self.send_file(file_path):
                successful_files.append(file_path)
                print(f"✅ 文件 {i} 发送成功")
            else:
                failed_files.append(file_path)
                print(f"❌ 文件 {i} 发送失败")
                
                # 询问是否继续
                if i < total_files:
                    continue_choice = input(f"\n是否继续发送剩余 {total_files - i} 个文件? (y/n): ").lower()
                    if continue_choice != 'y':
                        print("用户取消后续文件传输")
                        # 将剩余文件标记为跳过
                        remaining_files = file_paths[i:]
                        failed_files.extend(remaining_files)
                        break
        
        # 显示总结
        print("\n" + "=" * 50)
        print(f"传输完成! 成功: {len(successful_files)}, 失败: {len(failed_files)}")
        
        if successful_files:
            print("\n✅ 成功传输的文件:")
            for file_path in successful_files:
                print(f"  - {os.path.basename(file_path)}")
        
        if failed_files:
            print("\n❌ 传输失败的文件:")
            for file_path in failed_files:
                print(f"  - {os.path.basename(file_path)}")
        
        return len(successful_files), len(failed_files)
    
    def send_file(self, file_path):
        """发送文件到服务端"""
        if not os.path.exists(file_path):
            print(f"错误: 文件不存在 - {file_path}")
            return False
        
        file_size = os.path.getsize(file_path)
        filename = os.path.basename(file_path)
        
        print(f"准备发送文件: {filename}")
        print(f"文件大小: {file_size / (1024*1024):.2f} MB")
        print(f"目标服务器: {self.server_host}:{self.server_port}")
        print()
        
        try:
            # 连接到服务器
            client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            client_socket.settimeout(30)  # 30秒超时
            
            print("正在连接服务器...")
            client_socket.connect((self.server_host, self.server_port))
            print("连接成功!")
            
            # 发送文件名长度和文件名
            filename_bytes = filename.encode('utf-8')
            client_socket.send(len(filename_bytes).to_bytes(4, 'big'))
            client_socket.send(filename_bytes)
            
            # 发送文件大小
            client_socket.send(file_size.to_bytes(8, 'big'))
            
            # 发送文件数据
            sent_size = 0
            buffer_size = 8192
            
            print("开始发送文件数据...")
            with open(file_path, 'rb') as f:
                while sent_size < file_size:
                    chunk = f.read(buffer_size)
                    if not chunk:
                        break
                    
                    # 确保整个chunk都被发送
                    chunk_sent = 0
                    while chunk_sent < len(chunk):
                        try:
                            bytes_sent = client_socket.send(chunk[chunk_sent:])
                            if bytes_sent == 0:
                                raise RuntimeError("Socket连接已断开")
                            chunk_sent += bytes_sent
                        except socket.error as e:
                            print(f"\n发送数据时出错: {e}")
                            return False
                    
                    sent_size += len(chunk)
                    
                    # 显示进度
                    progress = (sent_size / file_size) * 100
                    print(f"\r发送进度: {progress:.1f}% ({sent_size}/{file_size})", end='')
            
            if sent_size == file_size:
                print(f"\n✅ 文件数据发送完整: {sent_size} 字节")
            else:
                print(f"\n❌ 文件数据发送不完整: {sent_size}/{file_size} 字节")
                return False
            
            print("\n文件发送完成，等待服务器响应...")
            
            # 接收服务器响应
            try:
                response_length_data = client_socket.recv(4)
                if len(response_length_data) == 4:
                    response_length = int.from_bytes(response_length_data, 'big')
                    response = client_socket.recv(response_length).decode('utf-8')
                    print(f"服务器响应: {response}")
                else:
                    print("未收到服务器响应")
            except (socket.timeout, ConnectionResetError, OSError):
                # 服务器已主动断开连接，这是正常的
                print("服务器已主动断开连接")
            
            print(f"[{datetime.now().strftime('%H:%M:%S')}] 文件传输完成!")
            return True
            
        except ConnectionRefusedError:
            print(f"错误: 无法连接到服务器 {self.server_host}:{self.server_port}")
            if self.server_host == '127.0.0.1' or self.server_host == 'localhost':
                print("💻 本地测试提示: 请先在另一个终端运行 'python server.py'")
            else:
                print("请确保服务端在Android Termux中正在运行")
        except socket.timeout:
            print("错误: 连接超时")
        except Exception as e:
            print(f"错误: {e}")
        finally:
            # 客户端也尝试关闭连接（如果还没有被关闭）
            try:
                client_socket.close()
            except:
                pass
        
        return False

def get_android_ip():
    """获取Android设备的IP地址提示"""
    print("📱 如何获取Android设备IP地址:")
    print("1. 在Android Termux中运行: ip route | grep wlan")
    print("2. 或者运行: ifconfig wlan0")
    print("3. 或者在设置-WiFi中查看IP地址")
    print("\n💻 本地测试:")
    print("1. 终端1: python server.py")
    print("2. 终端2: python client.py 127.0.0.1 test.mp4")
    print()

def main():
    import argparse
    import glob
    
    parser = argparse.ArgumentParser(
        description='文件发送客户端',
        epilog="本地测试: python client.py 127.0.0.1 video.mp4 | Android: python client.py 192.168.1.100 video.mp4"
    )
    parser.add_argument('server_ip', help='Android设备的IP地址')
    parser.add_argument('file_paths', nargs='*', help='要发送的文件路径（支持多个文件）')
    parser.add_argument('--port', type=int, default=8888, help='服务器端口 (默认: 8888)')
    
    args = parser.parse_args()
    
    # 如果没有提供文件路径，就显示帮助信息
    if not args.file_paths:
        get_android_ip()
        
        # 查找当前目录下的mp4文件
        mp4_files = glob.glob("*.mp4")
        if mp4_files:
            print(f"当前目录下发现的MP4文件:")
            for i, file in enumerate(mp4_files, 1):
                size_mb = os.path.getsize(file) / (1024*1024)
                print(f"  {i}. {file} ({size_mb:.1f} MB)")
            print()
        
        print("使用方法:")
        print(f"  📱 Android: python {sys.argv[0]} <Android_IP> <文件路径1> [文件路径2] [...]")
        print(f"  💻 本地测试: python {sys.argv[0]} 127.0.0.1 <文件路径1> [文件路径2] [...]")
        print(f"\n示例:")
        print(f"  单个文件: python {sys.argv[0]} 192.168.1.100 video.mp4")
        print(f"  多个文件: python {sys.argv[0]} 192.168.1.100 *.mp4")
        print(f"  本地测试: python {sys.argv[0]} 127.0.0.1 video.mp4")
        return
    
    # 过滤存在的文件
    existing_files = []
    missing_files = []
    
    for file_path in args.file_paths:
        if os.path.exists(file_path):
            existing_files.append(file_path)
        else:
            missing_files.append(file_path)
    
    if missing_files:
        print("⚠️ 以下文件不存在，将被跳过:")
        for file_path in missing_files:
            print(f"  - {file_path}")
        print()
    
    if not existing_files:
        print("❌ 没有找到可发送的文件!")
        return
    
    # 创建客户端并发送文件
    client = FileSendClient(args.server_ip, args.port)
    
    if len(existing_files) == 1:
        # 单个文件
        success = client.send_file(existing_files[0])
        if success:
            print("\n✅ 文件发送成功!")
        else:
            print("\n❌ 文件发送失败!")
            get_android_ip()
    else:
        # 多个文件
        success_count, failed_count = client.send_files(existing_files)
        if failed_count == 0:
            print(f"\n🎉 所有 {success_count} 个文件发送成功!")
        elif success_count == 0:
            print(f"\n💥 所有 {failed_count} 个文件发送失败!")
            get_android_ip()
        else:
            print(f"\n⚡ 部分完成: {success_count} 成功, {failed_count} 失败")

if __name__ == '__main__':
    main()